/**
 * Filename \CommonUtil.java 2021年02月26日
 * Copyright © Ehome Co.Ltd. All Rgiths Reserved.
 *
 * @author wuyingchao
 */
package com.ehome.poct.core.api.dto.common;

import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.ehome.poct.core.api.dto.TestDataDTO;
import com.ehome.poct.core.api.dto.check.gold.TestConfPoctStripTypeDTO;
import com.google.common.base.Joiner;
import lombok.extern.slf4j.Slf4j;
import org.junit.platform.commons.util.StringUtils;

import java.math.BigDecimal;
import java.security.MessageDigest;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 公共工具类
 *
 * @author wyc
 * @date 2021/02/26 10:45
 **/
@Slf4j
public class CommonUtil {
    /**
     * CRP Code
     */
    public static final Integer CRP_TYPE_CODE = 4;
    public static final Integer SAA_TYPE_CODE = 5;
    public static final Integer[]  DL_STRIP_TYPE = new Integer[]{4,5,11,21,12};
    public static final Integer MALB_TPYE_CODE = 11;
    public static final Integer H_MALB_TPYE_CODE = 21;
    /**
     * CRP 标定值
     */
    public static final  BigDecimal CRP_VALUE = BigDecimal.valueOf(10);
    public static final BigDecimal CRP_MAX_VALUE = BigDecimal.valueOf(150);
    public static final BigDecimal SAA_MAX_VALUE = BigDecimal.valueOf(200);

    /**
    *细分检测项目类型 和 检测项目代码
    */
    //改了 7 和 8 的位置 让 程序先看8 如果有8就不考虑7
    public static final String[] projectLabels = new String[]{"HCG","LH","FSH","MP-IgM","HP-IgM/IgG","HP","MP-Ab","mALb","HbA1C","EV71-IgM","CVA16-IgM","FluA+B-Ag","Cpn-IgM","CRP","SAA","血常规"};
    public static final int[] projectCodes  = new int[]{1,2,3,6,8,7,9,11,12,14,15,16,17,4,5,100,121};
    /**
     * 转译检测值
     *
     * @param strip 检测项目
     * @param value 检测值
     * @param max   最大有效值
     * @param min   最小有效值
     * @return
     */
    public static String translateTestValue(TestConfPoctStripTypeDTO stripTypeDTO, Integer strip, BigDecimal value, BigDecimal max, BigDecimal min, Integer isChild) {
        String upDownFlag = "";
        if(null!=isChild){
            upDownFlag=  translateUpDownFlag(stripTypeDTO,value,isChild);
        }
        // CRP检测
        if (strip.equals(CRP_TYPE_CODE)) {
            //大于8 数据放在常规 后面
            if (value.compareTo(CRP_VALUE) >= 0) {
                if (value.compareTo(max) >= 0) {
                    return "常规:≥" + max +upDownFlag+ "<br/>超敏:≥10.00";
                } else {
                    return "常规:" + value +upDownFlag+ "<br/>超敏:≥10.00";
                }
            }
            //小于 10 数据放在超敏后面
            else {
                //大于参考范围最小值
                    return "常规:<10.00<br/>超敏:" + value +upDownFlag;
            }
        }
        // 其他检测
        else {
            if (value.compareTo(max) >= 0) {
                return "≥" + max +upDownFlag;
            } else if (value.compareTo(min) <= 0) {
                return "≤" + min +upDownFlag;
            }
        }
        return value +upDownFlag;
    }

    /**
     * 转译检测值
     *
     * @param strip
     * @param value
     * @param max
     * @param min
     * @return
     */
    public static String translateTestValue(TestConfPoctStripTypeDTO strip, String value, BigDecimal max, BigDecimal min,Integer isChild) {
        try {
            return translateTestValue(strip,strip.getTypeCode(), new BigDecimal(value), max, min,isChild);
        } catch (Exception e) {
            return value;
        }
    }

    /**
     * 转义 值在参考范围内的上下箭头
     * @param strip
     * @param value
     * @param isChild
     * @return
     */
    public static String translateUpDownFlag(TestConfPoctStripTypeDTO strip,BigDecimal value,Integer isChild){
        if(null ==strip) {return "";}
        if(ArrayUtil.contains(DL_STRIP_TYPE,strip.getTypeCode())){
            //拆解参考范围 尿微量的只有<20
            if(strip.getTypeCode().equals(MALB_TPYE_CODE) || strip.getTypeCode().equals(H_MALB_TPYE_CODE))
            {
                BigDecimal stand = new BigDecimal( strip.getReference().replace("<",""));
                if(value.compareTo(stand)>0) {return "↑";};
            }
            else {
                String reference = strip.getReference();

                if(StrUtil.isEmpty(reference)) {
                    //再取一次成人标准
                    reference = strip.getStandardReference();
                }
                if(0==isChild){
                    reference = StrUtil.isNotEmpty(strip.getChildReference())?strip.getChildReference():reference;
                }
                if(StrUtil.isEmpty(reference)) { return  "";}
                BigDecimal low = new BigDecimal(reference.substring(0, reference.indexOf("~")));
                BigDecimal high = new BigDecimal(reference.substring(reference.indexOf("~")+1));
                if(low.compareTo(value)>0) {return "↓";};
                if(high.compareTo(value)<0) {return  "↑";}
            }
        }
        return "";
    }

    /**
     * 转译检测值
     *
     * @param strip
     * @param value
     * @param max
     * @param min
     * @return
     */
    public static String translateTestValue(Integer strip, String value, BigDecimal max, BigDecimal min,Integer isChild) {
        try {
            return translateTestValue(null, strip, new BigDecimal(value), max, min,isChild);
        } catch (Exception e) {
            return value;
        }
    }
    /**
     * 转译检测值
     *
     * @param data  检测数据
     * @param value 检测值
     * @return
     */
    public static String translateTestData(TestDataDTO data, String value, Integer isChild) {
        // 定性值，不需要组装
        if (data.getStripType().getType() == 2) {
            return value;
        }
        return translateTestValue(data.getStripType(), data.getStripTypeCode(), new BigDecimal(value),
                data.getStripMapping().getMax(), data.getStripMapping().getMin(),isChild);
    }

    /**
     * 转译检测值
     *
     * @param data  检测数据
     * @param value 检测值
     * @return
     */
    public static String translateTestData(TestDataDTO data, BigDecimal value,Integer isChild) {
        return translateTestValue(data.getStripType(), data.getStripTypeCode(), value,
                data.getStripMapping().getMax(), data.getStripMapping().getMin(),isChild);
    }

    /**
     * 根据颜色和值创建HTML标签
     *
     * @param color 颜色
     * @param value 值
     * @return
     */
    public static String createHtmlTag(String color, String value) {
        return "<font color='" + color + "'>" + value + "</font>";
    }

    public static JSONObject getCUserInfoByOpenId(String accessToken,String openId, String language){
        String url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token="+accessToken+"&openid="+openId+"&lang="+language;
        String get = HttpUtil.get(url);
        JSONObject json = JSONUtil.parseObj(get);
        return json;
    }

    //扫描二维码事件后推送模板消息的接口
    public static JSONObject sendMessage2(String accessToken, String openId, String templateId, String pagePath, String[] reportData){
        //String url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/bizsend?access_token="+  accessToken;
        String url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token="+accessToken;
        JSONObject body = new JSONObject();
        body.set("touser",openId);
        body.set("template_id", templateId);
        body.set("url", pagePath);
        JSONObject data = new JSONObject();
        JSONObject v1 = new JSONObject();
        v1.set("value",reportData[0]);
        JSONObject v2 = new JSONObject();
        v2.set("value",reportData[1]);
        JSONObject first = new JSONObject();
        first.set("value","您好!您之前进行的检验项目已出结果,详情如下");
        first.set("color","#87CEFA");
        data.set("first","您的检测报告结果已出，请查收");
        JSONObject remark =new JSONObject();
        remark.set("value","-->点击查看详情");
        remark.set("color","#836FFF");
        data.set("first",first);
        data.set("test",v1);
        data.set("testdate",v2);
        data.set("remark",remark);
        body.set("data", data);
        String post = HttpUtil.post(url, body.toString());
        JSONObject json = JSONUtil.parseObj(post);
        return json;
    }
    //标准化省份名称 保存为 String 数组输出 第一项为英文名 第二项为中文名 第三项为省份id
    public static String[] normalizeProvinceNameAndId(String province){
        String[] result = new String[3];
        if(province.contains("410000")){
            result[0]= "HENAN";
            result[1]= "河南省";
            result[2]= "16";
        }
        else if(province.contains("130000")){
            result[0]= "HEBEI";
            result[1]= "河北省";
            result[2]= "5";
        }
        else if(province.contains("310000")){
            result[0] = "SHANGHAI";
            result[1] = "上海市";
            result[2] = "4";
        }
        else if(province.contains("370000")){
            result[0]= "SHANDONG";
            result[1]= "山东省";
            result[2]= "15";
        }
        else if(province.contains("510000")){
            result[0]= "SICHUAN";
            result[1]= "四川省";
            result[2]= "21";
        }
        else if(province.contains("140000")){
            result[0]= "SHANXI";
            result[1]= "山西省";
            result[2]= "6";
        }
        else if(province.contains("340000")){
            result[0]= "ANHUI";
            result[1]= "安徽省";
            result[2]= "12";
        }
        else if(province.contains("230000")){
            result[0]= "HEILONGJIANG";
            result[1]= "黑龙江省";
            result[2]= "9";
        }
        else if(province.contains("220000")){
            result[0]= "JILIN";
            result[1]= "吉林省";
            result[2]= "8";
        }
        else if(province.contains("210000")){
            result[0]= "LIAONING";
            result[1]= "辽宁省";
            result[2]= "7";
        }
        else if(province.contains("330000")){
            result[0]= "ZHEJIANG";
            result[1]= "浙江省";
            result[2]= "11";
        }
        else if(province.contains("500000")){
            result[0]= "CHONGQING";
            result[1]= "重庆市";
            result[2]= "3";
        }
        else if(province.contains("420000")){
            result[0]= "HUBEI";
            result[1]= "湖北省";
            result[2]= "17";
        }
        else if(province.contains("320000")){
            result[0]= "JIANGSU";
            result[1]= "江苏省";
            result[2]= "10";
        }
        else if(province.contains("520000")){
            result[0]= "GUIZHOU";
            result[1]= "贵州省";
            result[2]= "22";
        }
        else if(province.contains("430000")){
            result[0]= "HUNAN";
            result[1]= "湖南省";
            result[2]= "18";
        }
        else if(province.contains("530000")){
            result[0]= "YUNAN";
            result[1]= "云南省";
            result[2]= "23";
        }
        else if(province.contains("350000")){
            result[0]= "FUJIAN";
            result[1]= "福建省";
            result[2]= "13";
        }
        else if(province.contains("150000")){
            result[0]= "NEIMENG";
            result[1]= "内蒙古自治区";
            result[2]= "28";
        }
        else if(province.contains("360000")){
            result[0]= "JIANGXI";
            result[1]= "江西省";
            result[2]= "14";
        }
        else if(province.contains("610000")){
            result[0]= "SHANXI";
            result[1]= "陕西省";
            result[2]= "24";
        }
        else if(province.contains("110000")){
            result[0]= "BEIJING";
            result[1]= "北京市";
            result[2]= "1";
        }
        else if(province.contains("120000")){
            result[0]= "TIANJIN";
            result[1]= "天津市";
            result[2]= "2";
        }
        else if(province.contains("450000")){
            result[0]= "GUANGXI";
            result[1]= "广西壮族自治区";
            result[2]= "29";
        }
        else if(province.contains("440000")){
            result[0]= "GUANGDONG";
            result[1]= "广东省";
            result[2]= "19";
        }
        else if(province.contains("620000")){
            result[0]= "GANSU";
            result[1]= "甘肃省";
            result[2] ="25";
        }
        else if(province.contains("630000")){
            result[0]= "QINGHAI";
            result[1]= "青海省";
            result[2]= "26";
        }
        else if(province.contains("640000")){
            result[0]= "NINGXIA";
            result[1]= "宁夏回族自治区";
            result[2]= "31";
        }
        else if(province.contains("460000")){
            result[0]= "HAINAN";
            result[1]= "海南省";
            result[2]= "20";
        }
        else if(province.contains("测试")){
            result[0]= "CESHI";
            result[1]= "测试";
            result[2]= "101";
        }
        else if(province.contains("540000")){
            result[0]= "XIZANG";
            result[1]= "西藏自治区";
            result[2]= "30";
        }
        else if(province.contains("650000")){
            result[0]= "XINJIANG";
            result[1]= "新疆维吾尔自治区";
            result[2]= "32";
        }
        else if(province.contains("710000")){
            result[0] = "TAIWAN";
            result[1] = "台湾省";
            result[2] = "27";
        }
        else if(province.contains("810000")){
            result[0] = "XIANGGANG";
            result[1] = "香港特别行政区";
            result[2] = "33";
        }
        else if(province.contains("820000")){
            result[0] = "AOMEN";
            result[1] = "澳门特别行政区";
            result[2] = "34";
        }

        return result;
    }
    //对指定字符串进行sha1加密
    public static String sha1(String str) {
        char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
                'a', 'b', 'c', 'd', 'e', 'f' };
        try {
            MessageDigest mdTemp = MessageDigest.getInstance("SHA1");
            mdTemp.update(str.getBytes("UTF-8"));
            byte[] md = mdTemp.digest();
            int j = md.length;
            char buf[] = new char[j * 2];
            int k = 0;
            for (int i = 0; i < j; i++) {
                byte byte0 = md[i];
                buf[k++] = hexDigits[byte0 >>> 4 & 0xf];
                buf[k++] = hexDigits[byte0 & 0xf];
            }
            return new String(buf);
        } catch (Exception e) {
            return null;
        }
    }

    public static List<Integer> getProjectCodes(String projectName){
        List<Integer> myProjectCodes = new ArrayList<>();
        for(int i=0;i<projectLabels.length;i++){
            String projectLabel = projectLabels[i];
            //如果已经包含 "HP-IgM/IgG" 则跳过查询 "HP"
            if(myProjectCodes.contains(8) && projectLabel.equals("HP")){
                continue;
            }
            if(projectName.contains(projectLabel)){
                myProjectCodes.add(projectCodes[i]);
            }
        }
        if(myProjectCodes.contains(4) && myProjectCodes.contains(5) && myProjectCodes.contains(100)){
            myProjectCodes.remove(Integer.valueOf(4));
            myProjectCodes.remove(Integer.valueOf(5));
            myProjectCodes.remove(Integer.valueOf(100));
            myProjectCodes.add(121);
        }
        return myProjectCodes;
    }

    /*
    生成 普通文本消息回复的xml字符串
    ToUserName  接收方帐号（收到的OpenID）
    FromUserName 开发者微信号
    CreateTime 消息创建时间 （整型）
    MsgType 消息类型，文本为text
    Content 回复的消息内容（换行：在content中能够换行，微信客户端就支持换行显示）

     */
    public static String createResponseMessageXml(String ToUserName, String FromUserName, String CreateTime, String Content){
        String xml = "<xml>" +
                "<ToUserName><![CDATA["+ToUserName+"]]></ToUserName>"+
                "<FromUserName><![CDATA["+FromUserName+"]]></FromUserName>" +
                "<CreateTime>"+CreateTime+"</CreateTime>" +
                "<MsgType><![CDATA[text]]></MsgType>" +
                "<Content><![CDATA["+Content+"]]></Content>" +
                "</xml>";
        return xml;
    }

    private static boolean isEmojiCharacter(char codePoint) {
        return (codePoint == 0x0) || (codePoint == 0x9) || (codePoint == 0xA)
                || (codePoint == 0xD)
                || ((codePoint >= 0x20) && (codePoint <= 0xD7FF))
                || ((codePoint >= 0xE000) && (codePoint <= 0xFFFD))
                || ((codePoint >= 0x10000) && (codePoint <= 0x10FFFF));
    }

    /**
     * 过滤emoji 或者 其他非文字类型的字符
     *
     * @param source
     * @return
     */
    public static String filterEmoji(String source) {
        if (StringUtils.isBlank(source)) {
            return source;
        }
        StringBuilder buf = null;
        int len = source.length();
        for (int i = 0; i < len; i++) {
            char codePoint = source.charAt(i);
            if (isEmojiCharacter(codePoint)) {
                if (buf == null) {
                    buf = new StringBuilder(source.length());
                }
                buf.append(codePoint);
            }
        }
        if (buf == null) {
            return source;
        } else {
            if (buf.length() == len) {
                buf = null;
                return source;
            } else {
                return buf.toString();
            }
        }
    }

    /**
     * 样本内容 组装排线
     * @param sampleType
     * @return
     */
    public static String processSample(String ... sampleType) {
        final Set<String> set = new HashSet<>();
        for (String str : sampleType) {
            set.addAll(Arrays.asList(str.split("，")));
        }
        return  Joiner.on("，").join(set.stream().sorted(String::compareTo).collect(Collectors.toList()));
    }
    /**
     * 样本内容 组装排线
     * @param sampleType
     * @return
     */
    public static String processSample(List<String>  sampleType) {
        final Set<String> set = new HashSet<>();
        for (String str : sampleType) {
            set.addAll(Arrays.asList(str.split("，")));
        }
        return  Joiner.on("，").join(set.stream().sorted(String::compareTo).collect(Collectors.toList()));
    }
    /**
     * 传入 <font color='#68BE7D'>常规:<10<br/>超敏:0.912500</font>
     * 返回两个<font color='#68BE7D'>内容</font>
     * @param result
     * @return
     */
    public static String[] processCrpSaaSuper(String result)
    {
        String[] arr = new String[2];
        if(StrUtil.isNotBlank(result)){
            int normalStart = result.indexOf("常规");
            int superStart = result.indexOf("超敏");
            int lastFont = result.indexOf("</font>");
            int tapStart = result.indexOf("<br/>");
            String start = result.substring(0,normalStart);
            String end =  result.substring(lastFont);
            arr[0] = start + result.substring(normalStart+3,tapStart) + end;
            arr[1] =  start+ result.substring(superStart+3,lastFont) + end;
        }
        return arr;
    }

    /**
     * 传入 常规:<10<br/>超敏:0.912500
     * 返回两个 内容值
     * @param result
     * @return
     */
    public static String[] processCrpSaaSuperNoHtml(String result){
        String[] arr = new String[2];
        if(StrUtil.isNotBlank(result)){
            int superStart = result.indexOf("超敏");
            int normalStart = result.indexOf("常规");
            arr[0] = result.substring(normalStart==-1?0:normalStart+3,superStart);
            arr[1] = result.substring(superStart==-1?0:superStart+3) ;
        }
        return arr;
    }
}